#include <iostream>
#include <list>
#include <memory>
using std::cout;
using std::endl;
using std::list;
using std::unique_ptr;

class Observer{
public:
    virtual void update(int status) = 0;
protected:
    int _status;
};

class Observer1:public Observer{
    public:
        void update(int status) override{
            _status = status;
            cout << "Observer1 status is been set to "<< _status << endl;
        }
};
class Observer2:public Observer{
    public:
        void update(int status)override{
            _status = status;
            cout << "Observer2 status is been set to "<< _status << endl;
        }
};

class Subject{
    public:
        virtual void attach(Observer * ob)=0;
        virtual void detach(Observer * ob)=0;
        virtual void notify() = 0;
        virtual void setStatus(int status) = 0;
        virtual ~Subject(){}
protected:
    list<Observer *> ob_list;
    int _status;
};

class concretSubject:public Subject{
public:
    concretSubject(){}
    void attach(Observer * ob)override{
        ob_list.push_back(ob);
    }
    void detach(Observer * ob) override{
        ob_list.remove(ob);
    }
    void notify() override{
        for(auto &ob : ob_list){
            ob->update(_status);
        }
    }
    void setStatus(int status)override{
        _status = status;
    }
    ~concretSubject(){}
};

void test(){
    unique_ptr<Observer> ob1(new Observer1());    
    unique_ptr<Observer> ob2(new Observer2());    
    
    unique_ptr<Subject> sub(new concretSubject());    
    sub->attach(ob1.get());
    sub->attach(ob2.get());
    sub->setStatus(1);
    sub->notify();
    cout << "-------------"<< endl;
    sub->detach(ob1.get());
    sub->setStatus(2);
    sub->notify();
}

int main()
{
    

    test ();
    return 0;
}

